package com.ysx66.verification.base.service.impl;

import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.UUID;

import javax.imageio.ImageIO;

import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.ysx66.verification.base.domain.ImagePoint;
import com.ysx66.verification.base.domain.ImageVerify;
import com.ysx66.verification.base.service.VerifyService;

import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.Thumbnails.Builder;
import net.coobird.thumbnailator.geometry.Coordinate;
import net.coobird.thumbnailator.geometry.Position;

@Service("verifyService")

public class VerifyServiceImpl implements VerifyService{
	
	static {
		System.out.println("--------------初始化路径----------------");
		File f = new File("D:/ImgVerify/whole");
		if(!f.exists()){
			f.mkdirs();
		}
		File f2 = new File("D:/ImgVerify/repair");
		if(!f2.exists()){
			f2.mkdirs();
		}
	}
	
	
	@Autowired
	private StringRedisTemplate redisTemplate;
	
	
	public void setRedisTemplate(StringRedisTemplate redisTemplate) {this.redisTemplate = redisTemplate;}
	
	@Override
	public void generate(int size) {
		for (int i = 0; i<=size ; i++) {
			generate();
		}
	}
	
	
	@Override
	public void generate(){
		String baseDir = VerifyServiceImpl.class.getResource("/").getPath();
		String originalUrl = baseDir +"test.jpg";
		String alphaUrl = baseDir + "90.jpg";
		String verifyHome = "D:/ImgVerify/";
		int width = 300;
		int height = 150;
		int repairWidth = 50;
		int repairHeight = 50;
		int wholeItemWidth = 30;
		int wholeItemHeight = 15;
		try {
			generate(originalUrl, alphaUrl, verifyHome, width, height, repairWidth, repairHeight, wholeItemWidth, wholeItemHeight);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public boolean verify(String code,int x,int y){
		boolean result = redisTemplate.hasKey(code);
		if(result){
			return true;
		}
		return false;
	}
	
	

	private void generate(String originalUrl,String alphaUrl,String verifyHome
						,int width,int height
						,int repairWidth,int repairHeight
						,int wholeItemWidth,int wholeItemHeight) throws Exception{
		if(width % wholeItemWidth != 0 
				|| height % wholeItemHeight != 0){
			throw new RuntimeException("破图图形错误!");
		}
		Random random = new Random();
		// 获取随机位置范围
		int x_ = random.nextInt(width-repairWidth) % (width-repairWidth*2 + 1) + repairWidth;
		int y_ = random.nextInt(height-repairHeight) % (height-repairHeight*2 + 1) + repairHeight;
		
		ImageVerify verify = new ImageVerify();
		verify.setInValid(DateUtils.addMinutes(new Date(), 10));
		verify.setOriginal(originalUrl);
		verify.setOffset(10);
		verify.setX(x_);
		verify.setY(y_);
		verify.setVerifyCode(UUID.randomUUID().toString());
		verify.setRepairWidth(repairWidth);
		verify.setRepairHeight(repairHeight);
		
		// 生产破图
		// 1.产生模糊图层
		Builder<File> alpha = Thumbnails.of(alphaUrl)
//						.sourceRegion(verify.getX(),verify.getY(), repairWidth, repairHeight)
						.size(repairWidth, repairHeight).keepAspectRatio(true);
		
		Position position = new Coordinate((int)verify.getX(), (int)verify.getY());
		BufferedImage whole = Thumbnails.of(verify.getOriginal())
								        .watermark(position, alpha.asBufferedImage(), 0.3f) 
								        .outputQuality(1)//生成质量100%  
								        .scale(1)//缩放比例 
								        .asBufferedImage();
		int x = wholeItemWidth;
		int y = wholeItemHeight;
		int itemWidth = width/x;
		int itemHeight = height/y;
		int currentX = 0;
		int currentY = 0;
		List<ImagePoint> images = new ArrayList<ImagePoint>();
		for (int h = 0;h < y ; h++) {
			for(int w = 0;w < x; w++){
				ImagePoint point = new ImagePoint();
				point.setX(currentX);
				point.setY(currentY);
				BufferedImage item = Thumbnails.of(whole).sourceRegion(currentX,currentY, itemWidth, itemHeight)
							.size(itemWidth, itemHeight).keepAspectRatio(true).asBufferedImage();
				point.setImage(item);
				currentX += itemWidth;
				images.add(point);
			}
			currentX = 0;
			currentY = itemHeight * ( h+1 );
		}
		Collections.shuffle(images);
		currentX = 0;
		currentY = 0;
		JsonObject object = new JsonObject();
		object.addProperty("width", width);
		object.addProperty("height", height);
		object.addProperty("itemWidth", itemWidth);
		object.addProperty("itemHeight", itemHeight);
		JsonArray array = new JsonArray();
		BufferedImage imageNew = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		for (int h = 0;h < y ; h++) {
			for(int w = 0;w < x; w++){
				ImagePoint point = images.get(0);
				JsonObject element = new JsonObject();
				element.addProperty("x", point.getX());
				element.addProperty("y", point.getY());
				images.remove(0);
				int[] imageArray = new int[itemWidth*itemHeight];
				imageArray = point.getImage().getRGB(0,0,itemWidth,itemHeight,imageArray,0,itemWidth);
				imageNew.setRGB(currentX,currentY,itemWidth,itemHeight,imageArray,0,itemWidth);//设置右半部分的RGB
				currentX += itemWidth;
				array.add(element);
			}
			currentX = 0;
			currentY = itemHeight * ( h+1 );
		}
		object.add("point", array);
		
		verify.setPoint(object.toString());			// 得到破图的坐标
		

		String wholeName = UUID.randomUUID().toString();
		String wholePath  = verifyHome + "whole/" + wholeName;
		
	    BufferedOutputStream wholeOut = new BufferedOutputStream(new FileOutputStream(wholePath));
	    ImageIO.write(imageNew, "png", wholeOut);		// 破图图片
	    
	    wholeOut.flush();
	    wholeOut.close();
	    String repairName = UUID.randomUUID().toString();
	    String repairPath = verifyHome + "repair/" + repairName;
	    
	    BufferedOutputStream repairOut = new BufferedOutputStream(new FileOutputStream(repairPath));
		// 得到补图
	    Thumbnails.of(verify.getOriginal()).sourceRegion((int)verify.getX(),(int)verify.getY(),repairWidth, repairHeight)
	    			.size(repairWidth, repairHeight).keepAspectRatio(true).toOutputStream(repairOut);
	    
	    repairOut.flush();
	    repairOut.close();
	    
	    verify.setWhole(wholePath);
	    verify.setRepair(repairPath);
	    
	    
	    ValueOperations<String, String> operations= redisTemplate.opsForValue();
		operations.set(verify.getVerifyCode(), JsonUtil.obj2json(verify));
		
	}
	
	private static class JsonUtil{
		private final static ObjectMapper objectMapper = new ObjectMapper();  
		
//		public static <T> T json2pojo(String jsonStr, Class<T> clazz)  throws Exception {  
//			return objectMapper.readValue(jsonStr, clazz);  
//		}
		
		public static String obj2json(Object obj) throws Exception {  
	        return objectMapper.writeValueAsString(obj);  
	    } 
	}

	

}
